package com.bw.educate.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bw.educate.client.CourseTeacher;
import com.bw.educate.common.ResponseResult;
import com.bw.educate.common.es.CourseBase;
import com.bw.educate.entity.*;
import com.bw.educate.mapper.EduCategoryChildMapper;
import com.bw.educate.mapper.EduCourseBaseMapper;
import com.bw.educate.mapper.EduCourseSectionMapper;
import com.bw.educate.repository.EduCourseRepository;
import com.bw.educate.service.IEduCategoryChildService;
import com.bw.educate.service.IEduCourseBaseService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.io.IOUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 在线教育-五组
 * @since 2020-08-12
 */
@Service
public class EduCourseBaseServiceImpl extends ServiceImpl<EduCourseBaseMapper, EduCourseBase> implements IEduCourseBaseService {

    @Autowired
    private EduCourseBaseMapper courseBaseMapper;

    @Autowired
    private EduCategoryChildMapper categoryChildMapper;

    @Autowired
    private EduCourseSectionMapper courseSectionMapper;

    @Autowired
    private EduCourseRepository courseRepository;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private IEduCategoryChildService categoryChildService;

    @Autowired
    private CourseTeacher courseTeacher;

//    private String coursePath="E:\\java\\shixun\\education\\code\\view\\educate-C\\course\\";

   // private String coursePath="D:\\webStorm\\1711Avue\\erp02\\educate\\code\\view\\educate-C\\course\\";
    //private String coursePath="D:\\1711A-NEW\\education\\code\\view\\educate-C\\course\\";
    //private String coursePath="D:\\1711A\\education\\educate\\code\\view\\educate-C\\course\\";

    //private String coursePath="D:\\webStorm\\1711Avue\\erp02\\educate\\code\\view\\educate-C\\course\\";
//    private String coursePath="D:\\1711A-NEW\\education\\code\\view\\educate-C\\course\\";
    private String coursePath="D:\\1711A\\education\\educate\\code\\view\\educate-C\\course\\";




    /**
     * 课程列表，模糊查询
     **/
    @Override
    public ResponseResult listAll(int currentPage, int pageSize, EduCourseBase courseBase) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            PageHelper.startPage(currentPage,pageSize);
            QueryWrapper queryWrapper = new QueryWrapper();
            if(courseBase.getCourseName()!=null){
                queryWrapper.like("COURSE_NAME","%"+courseBase.getCourseName()+"%");//根据课程标题进行查询
            }
            if(courseBase.getCourseStatus()!=null){
                queryWrapper.eq("COURSE_STATUS",courseBase.getCourseStatus());//根据状态进行查询
            }
            if(courseBase.getCategoryParentId()!=null){
                queryWrapper.like("CATEGORY_PARENT_ID","%"+courseBase.getCategoryParentId()+"%");//根据专业进行查询
            }

            queryWrapper.eq("IS_DELETE",0);
            List list = courseBaseMapper.selectList(queryWrapper);

            PageInfo pageInfo = new PageInfo(list);

            result.setResult(pageInfo);
            result.setMessage("查询成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("查询失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 课程推荐列表，模糊查询
     **/
    @Override
    public ResponseResult listRecommend(int currentPage, int pageSize, EduCourseBase courseBase) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            PageHelper.startPage(currentPage,pageSize);
            QueryWrapper queryWrapper = new QueryWrapper();
            if(courseBase.getCourseName()!=null){
                queryWrapper.like("COURSE_NAME","%"+courseBase.getCourseName()+"%");//根据课程标题进行查询
            }
            if(courseBase.getCourseStatus()!=null){
                queryWrapper.eq("COURSE_STATUS",courseBase.getCourseStatus());//根据状态进行查询
            }
            if(courseBase.getRecommended()!=null){
                queryWrapper.eq("RECOMMENDED",courseBase.getRecommended());//根据推荐类型进行查询
            }

            queryWrapper.eq("RECOMMENDED",1);
            queryWrapper.eq("IS_DELETE",0);
            List list = courseBaseMapper.selectList(queryWrapper);

            PageInfo pageInfo = new PageInfo(list);

            result.setResult(pageInfo);
            result.setMessage("查询成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("查询失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 课程的添加
     **/
    @Override
    public ResponseResult addCourse(long userId,EduCourseBase courseBase) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {

            courseBase.setPubUser(userId);//发布人
            courseBase.setPubTime(new Date());//发布时间
            courseBase.setIsDelete(0);
            courseBase.setSortValue(0);//排序值
            courseBase.setRecommended(0);//是否推荐
            courseBaseMapper.insert(courseBase);//添加课程

            result.setMessage("添加成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("添加失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 课程的修改
     **/
    @Override
    public ResponseResult updateCourse(EduCourseBase courseBase) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {

            courseBaseMapper.updateById(courseBase);//修改课程

            result.setMessage("修改成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("修改失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 推荐课程的修改
     **/
    @Override
    public ResponseResult updateRecommend(EduCourseBase courseBase) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {

            courseBaseMapper.updateById(courseBase);//修改课程

            result.setMessage("修改成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("修改失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 课程的删除
     **/
    @Override
    public ResponseResult deleteCourseBase(int id) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            EduCourseBase eduCourseBase = courseBaseMapper.selectById(id);
            eduCourseBase.setIsDelete(1);

            courseBaseMapper.updateById(eduCourseBase);
            result.setMessage("逻辑删除成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("逻辑删除失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 课程推荐的删除
     **/
    @Override
    public ResponseResult removeRecommend(int id) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            EduCourseBase eduCourseBase = courseBaseMapper.selectById(id);
            eduCourseBase.setRecommended(0);

            courseBaseMapper.updateById(eduCourseBase);
            result.setMessage("删除成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("删除失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 专业一级分类列表
     **/
    @Override
    public ResponseResult parentList() {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("PARENT_ID",0);//二级分类表中为0的是一级分类
            List list = categoryChildMapper.selectList(queryWrapper);
            result.setResult(list);
            result.setMessage("查询成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("查询失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 专业一级的id查询二级分类
     **/
    @Override
    public ResponseResult childList(long id) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            EduCategoryChild eduCategoryChild = categoryChildMapper.selectById(id);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("PARENT_ID",eduCategoryChild.getId());//根据一级id查找二级id里面的父id
            List list = categoryChildMapper.selectList(queryWrapper);
            result.setResult(list);
            result.setMessage("查询成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("查询失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 查询当前id的课程
     **/
    @Override
    public ResponseResult findCourse(long id) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            EduCourseBase eduCourseBase = courseBaseMapper.selectById(id);
            result.setResult(eduCourseBase);
            result.setMessage("查询成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("查询失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 查询当前id的推荐课程
     **/
    @Override
    public ResponseResult getByRecommendId(long id) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            EduCourseBase eduCourseBase = courseBaseMapper.selectById(id);
            result.setResult(eduCourseBase);
            result.setMessage("查询成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("查询失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 查询未推荐课程
     **/
    @Override
    public ResponseResult searchRecommend() {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("RECOMMENDED",0);
            List list = courseBaseMapper.selectList(queryWrapper);
            result.setResult(list);
            result.setMessage("查询成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("查询失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * ES模糊分页查询
     **/
    @Override
    public Page<CourseBase> eslist(Integer size, Integer page, EduCourseBase courseBase) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if(courseBase.getCategoryChildId()!=null){
            queryBuilder.must(QueryBuilders.termQuery("categoryChildId",courseBase.getCategoryChildId()));
        }
        if(courseBase.getCourseName()!=null && courseBase.getCourseName()!=""){
            queryBuilder.must(QueryBuilders.multiMatchQuery(courseBase.getCourseName(),"courseName","courseTitle"));
        }


        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("courseName");
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<span style=\"color:red\">");
        highlightBuilder.postTags("</span>");



        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();

        Pageable pageable = PageRequest.of(page, size);
        searchQueryBuilder.withPageable(pageable);
        searchQueryBuilder.withQuery(queryBuilder);
        searchQueryBuilder.withHighlightBuilder(highlightBuilder);


        return elasticsearchRestTemplate.queryForPage(searchQueryBuilder.build(), CourseBase.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
                List<CourseBase> list =new ArrayList<>();//定义结果集合
                for (SearchHit searchHit:searchResponse.getHits()) {//查询结果
                    CourseBase eduCourse = JSONObject.parseObject(searchHit.getSourceAsString(),com.bw.educate.common.es.CourseBase.class);

                    Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();

                    HighlightField coursename = highlightFields.get("courseName");
                    if(coursename!=null){
                        Text[] fragments = coursename.fragments();
                        String frmString = fragments[0].string();
                        eduCourse.setCourseName(frmString);
                    }

                    list.add(eduCourse);
                }
                if(list.size()>0){
                    return new AggregatedPageImpl<T>((List<T>) list,pageable,searchResponse.getHits().getTotalHits());
                }
                return null;
            }

            @Override
            public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
                return null;
            }
        });
    }

    /**
     * 通过定点的id展示课程信息
     **/
    @Override
    public ResponseResult getOrderById(List<EduCourseBase> courseBases) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            List<EduCourseBase> list = new ArrayList<>();
            for (EduCourseBase list1:courseBases){
                list.add(courseBaseMapper.selectById(list1.getId()));
            }

            result.setResult(list);
            result.setMessage("查询成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("查询失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 通过课程查询讲师信息
     **/
    @Override
    public ResponseResult findTeacher(long id) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            EduCourseBase eduCourseBase = courseBaseMapper.selectById(id);
            EduTeacher teacherById = courseTeacher.findTeacherById(eduCourseBase.getTeacherId());
            result.setResult(teacherById);
            result.setMessage("查询成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("查询失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 添加推荐课程
     **/
    @Override
    public ResponseResult getRecommend(long id) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            EduCourseBase eduCourseBase = courseBaseMapper.selectById(id);
            eduCourseBase.setRecommended(1);
            courseBaseMapper.updateById(eduCourseBase);
            result.setMessage("添加成功！！！");
        }catch (Exception e){
            result.setSuccess(false);
            result.setMessage("添加失败！！！"+e.toString());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 修改状态
     **/
    @Override
    public ResponseResult updateStatus(long id, int state) {
        ResponseResult result = ResponseResult.SUCCESS();
        try {
            EduCourseBase courseBase = courseBaseMapper.selectById(id);
            courseBase.setCourseStatus(state);
            if(state==2){
                //删除redis中的数据
                //redisTemplate.opsForHash().delete("courseList",String.valueOf(courseBase.getId()));
                //删除静态页面
                File file=new File(coursePath+courseBase.getId()+".html");
                file.delete();
                //删除es中的数据
                courseRepository.deleteAllByCourseId(id);
            }else {
                //吧数据添加到redis中
                //redisTemplate.opsForHash().put("courseList",String.valueOf(courseBase.getId()),courseBase);
                //生成静态页面
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("COURSE_ID", courseBase.getId());
                queryWrapper.eq("CHAPTER_ID",0);
                List<EduCourseSection> list = courseSectionMapper.selectList(queryWrapper);
                this.getHtml(courseBase,list);
                //把数据添加到es中this.id = this.$route.query.id;"education-course/chapter/getTree/"
                CourseBase course = new CourseBase();
                course.setCourseId(courseBase.getId());
                course.setCourseName(courseBase.getCourseName());
                course.setCourseTitle(courseBase.getCourseTitle());
                course.setCourseLogo(courseBase.getCourseLogo());
                course.setCategoryChildId(courseBase.getCategoryChildId());
                course.setCategoryParentId(courseBase.getCategoryParentId());
                course.setCourseHours(3L);
                course.setStudentsNumber(1000001L);
                course.setTimeCount(180L);
                courseRepository.save(course);
            }
            courseBaseMapper.updateById(courseBase);
            result.setMessage("修改成功");
        } catch (Exception e) {
            result.setSuccess(false);
            result.setMessage("修改失败" + e.toString());
        }
        return result;
    }


    //生成一个课程静态页面
    public void getHtml(EduCourseBase courseBase,List<EduCourseSection> list){

        try {

            EduTeacher teacherById = courseTeacher.findTeacherById(courseBase.getTeacherId());

            Configuration configuration=new Configuration(Configuration.getVersion());//创建模板引擎配置
            ClassPathResource classPathResource=new ClassPathResource("template");
            //加载模板的路径【文件目录或者文件夹】
            configuration.setDirectoryForTemplateLoading(classPathResource.getFile());
            configuration.setDefaultEncoding("utf-8");//设置编码格式
            Template template= configuration.getTemplate("coursecont.html");

            Map map=new HashMap();
            map.put("course", JSON.toJSONString(courseBase));
            map.put("courseList", JSON.toJSONString(list));
            map.put("teacher", JSON.toJSONString(teacherById));
            //模板+数据合成的具体的页面
            String htmlStr= FreeMarkerTemplateUtils.processTemplateIntoString(template,map);
            InputStream inputStream= IOUtils.toInputStream(htmlStr,"utf-8");//将字符串转换成输入流
            FileOutputStream outputStream=new FileOutputStream(coursePath+courseBase.getId()+".html");
            IOUtils.copy(inputStream,outputStream);
            outputStream.close();
            inputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
